package gov.nasa.anml.lifted;


import java.util.ArrayList;

import gov.nasa.anml.PDDL;
import gov.nasa.anml.State;
import gov.nasa.anml.PDDL.*;
import gov.nasa.anml.PDDL.Parameter;
import gov.nasa.anml.PDDL.Time;
import gov.nasa.anml.utility.SimpleFloat;
import gov.nasa.anml.utility.SimpleInteger;
import gov.nasa.anml.utility.SimpleObject;
import gov.nasa.anml.utility.SimpleVoid;

public class Chain extends IntervalImp implements Statement {
	
	public ArrayList<ChainableExpression<?,?>> expressions;
	
	public Chain() {super(); this.expressions = new ArrayList<ChainableExpression<?,?>>();}
	public Chain(ArrayList<ChainableExpression<?,?>> expressions) { super(); this.expressions = expressions; }
	
	public History<SimpleVoid> storage(State p, State c) {
		return null;
	}
	public boolean apply(State p, int contextID, State c) {
		return false;
	}
	
	
	public static final PDDL.Time splitFirst(PDDL.Time t) {
		switch(t) {
		case All:
			return PDDL.Time.Start;
		case StartHalf:
			return PDDL.Time.Start;
		case EndHalf:
			return PDDL.Time.Interim;
		// if crammed into splitting atomic pieces up....
		case Interim:
			// immediately before immediately after start = at start
			return PDDL.Time.Start;
		case Start:
			// should be immediately before start: ...start)
			return PDDL.Time.Start;
		case End:
			// should be immediately before end: ...end)
			// instead of (start, end)
			return PDDL.Time.Interim;
		case Timeless:
		default:
			return t;
		}
	}
	
	public static final PDDL.Time splitRest(PDDL.Time t) {
		switch(t) {
		case All:
			return PDDL.Time.EndHalf;
		case StartHalf:
			return PDDL.Time.Interim;
		case EndHalf:
			return PDDL.Time.End;
		// if forced to split atomic things...
		case Interim:
			return PDDL.Time.End;
		case Start:
			return PDDL.Time.Interim;
		case End:
			return PDDL.Time.End;
		case Timeless:
		default:
			return t;
		}
	}
	
	public static final PDDL.Time splitLeft(PDDL.Time t) {
		switch(t) {
		case All:
			return PDDL.Time.StartHalf;
		case StartHalf:
			return PDDL.Time.Start;
		case EndHalf:
			return PDDL.Time.Interim;
		case Interim:
		case Start:
		case End:
			return null;
		}
		return null;
	}
	
	public static final PDDL.Time splitRight(PDDL.Time t) {
		switch(t) {
		case All:
			return PDDL.Time.End;
		case StartHalf:
			return PDDL.Time.Interim;
		case EndHalf:
			return PDDL.Time.End;
		case Interim:
		case Start:
		case End:
			return t;
		}
		return null;
	}

	public void translateStmt(PDDL pddl, Interval unit, PDDL.Time part) {
		PDDL.Time t = PDDL.getShape(this);
		if (t == null || t == PDDL.Time.Timeless) {
			System.err.println("Shucks, Chain.java.");
			unit.getPDDLConditions().add(pddl.FalseCondition);
			return;
		}
		copyPDDL(unit);
		ChainableExpression<?,?> e;
		int i;
		for(i=0; i<expressions.size()-1;++i) {
			e = expressions.get(i);
			e.translateStmt(pddl,this,e.splitFirst(t));
			t = e.splitRest(t);
		}
		e = expressions.get(i);
		e.translateStmt(pddl,this,t);
	}
	
	public void translateDecl(PDDL pddl, Interval unit) {
		ChainableExpression<?,?> e;
		copyPDDL(unit);
		for(int i=0; i<expressions.size()-1;++i) {
			e = expressions.get(i);
			e.translateDecl(pddl,this);
		}
	}

}

